package com.dykj.fireFighting.web.base.analysis.controller;


import com.dykj.fireFighting.api.base.analysis.dto.ComprehensiveQueryDto;
import com.dykj.fireFighting.api.base.devHisResult.entity.DevHisResult;
import com.dykj.fireFighting.api.base.devHisResult.service.IDevHisResultService;
import com.dykj.fireFighting.api.base.enterprise.entity.Enterprise;
import com.dykj.fireFighting.api.base.enterprise.service.IEnterpriseService;
import com.dykj.fireFighting.api.base.maintenance.service.IUrgentMaintenanceService;
import com.dykj.fireFighting.api.base.statistic.SocialSocreVo;
import com.dykj.fireFighting.api.base.system.service.ISysDirectoryService;
import com.dykj.fireFighting.api.socialUnit.devHis.service.IDevHisService;
import com.dykj.fireFighting.api.socialUnit.dutymanger.service.IDutyRecordService;
import com.dykj.fireFighting.api.socialUnit.xfxg.service.IPatrolReportService;
import com.dykj.fireFighting.common.core.api.CommonResult;
import com.dykj.fireFighting.common.core.utils.DateBetweenUtil;
import com.dykj.fireFighting.common.core.vo.LoginUserVo;
import com.dykj.fireFighting.common.core.vo.PageVo;
import com.dykj.fireFighting.web.base.shiro.ShiroUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 综合查询-评估
 */
@Slf4j
@Api(value = "评估指数", tags = {"评估指数接口"})
@RestController
@RequestMapping("/zonghepinggu")
public class ZongHeAssessmentController {


    @DubboReference
    private IDevHisService devHisService;
    @DubboReference
    private IUrgentMaintenanceService urgentMaintenanceService;
    @DubboReference
    private IPatrolReportService iPatrolReportService;
    @DubboReference
    private IDutyRecordService iDutyRecordService;
    @DubboReference
    private IEnterpriseService iEnterpriseService;
    @DubboReference
    private IDevHisResultService devHisResultService;
    @DubboReference
    private ISysDirectoryService directoryService;


    /**
     * echarts数据排名榜
     *
     * @param comprehensiveQueryDto
     * @return
     * @throws Exception
     */
    @GetMapping("/rankingEcharts")
    public CommonResult<PageVo<SocialSocreVo>> getRankingEchartsData(ComprehensiveQueryDto comprehensiveQueryDto) throws ParseException {
        List<SocialSocreVo> socreVoList = new ArrayList<>();
        //监控中心查下辖的单位，社会单位查自己，管理员查全部社会单位
        List<Enterprise> list = new ArrayList<>();
        if (StringUtils.isBlank(comprehensiveQueryDto.getUnitIds())) {
            LoginUserVo loginUserVo = ShiroUtil.getUser();
            list = iEnterpriseService.queryUnitSelect(loginUserVo.getEnterpriseId().toString());
        } else {
            String[] unitIds = comprehensiveQueryDto.getUnitIds().split(",");
            for (String unitId : unitIds) {
                Enterprise enterprise = iEnterpriseService.getById(unitId);
                list.add(enterprise);
            }
        }

        //时间段月份
        List<String> monthList = DateBetweenUtil.getMonthBetween(comprehensiveQueryDto.getBeginTime(), comprehensiveQueryDto.getEndTime());
        String start = comprehensiveQueryDto.getBeginTime() + " 00:00:00";
        //获取数据
        for (int i = 0; i < monthList.size(); i++) {
            if (i != 0) {
                start = monthList.get(i).substring(0, 7) + "-01 00:00:00";
            }
            String end = monthList.get(i) + " 23:59:59";
            List<SocialSocreVo> monthSocreVoList = getSocialSocreVoList(list, start, end);
            socreVoList.addAll(monthSocreVoList);
        }

        //list排序
        //根据某个属性分组，汇总某个属性
        Map<String, LongSummaryStatistics> resultMap = new HashMap<>();
        if ("1".equals(comprehensiveQueryDto.getDataDimension())) {
            resultMap = socreVoList.stream().collect(Collectors.groupingBy(SocialSocreVo::getName, Collectors.summarizingLong(SocialSocreVo::getTotalScore)));
        } else if ("2".equals(comprehensiveQueryDto.getDataDimension())) {
            resultMap = socreVoList.stream().collect(Collectors.groupingBy(SocialSocreVo::getAreaName, Collectors.summarizingLong(SocialSocreVo::getTotalScore)));
        } else {
            resultMap = socreVoList.stream().collect(Collectors.groupingBy(SocialSocreVo::getIndustryName, Collectors.summarizingLong(SocialSocreVo::getTotalScore)));
        }

        List<SocialSocreVo> resultList = new ArrayList<>();
        resultMap.forEach((key, value) -> {
            SocialSocreVo result = new SocialSocreVo();
            result.setName(key);
            result.setTotalScore((int) Math.round(value.getAverage()));
            resultList.add(result);
        });

        //list排序
        Integer[] arr = {1};
        List<SocialSocreVo> returnSocreList = resultList.stream().sorted(Comparator.comparing(SocialSocreVo::getTotalScore).reversed())
                .peek(e -> e.setRanking(arr[0]++)).collect(Collectors.toList());

        //split page
        long page = comprehensiveQueryDto.getPage();
        long limit = 20;
        List<SocialSocreVo> subList = returnSocreList.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
        PageVo<SocialSocreVo> pageVo = new PageVo<>();
        pageVo.setList(subList);
        pageVo.setTotalCount(returnSocreList.size());
        return CommonResult.success(pageVo);
    }

    /**
     * echarts 趋势变化图
     *
     * @param comprehensiveQueryDto
     * @return
     * @throws Exception
     */
    @GetMapping("/trendEcharts")
    public CommonResult getAreaEchartsData(ComprehensiveQueryDto comprehensiveQueryDto) throws ParseException {
        Map<String, Object> resultData = new HashMap<>();
        Map<String, List<Double>> resultMap = new HashMap<>();
        //监控中心查下辖的单位，社会单位查自己，管理员查全部社会单位
        List<Enterprise> list = new ArrayList<>();
        if (StringUtils.isBlank(comprehensiveQueryDto.getUnitIds())) {
            LoginUserVo loginUserVo = ShiroUtil.getUser();
            list = iEnterpriseService.queryUnitSelect(loginUserVo.getEnterpriseId().toString());
        } else {
            String[] unitIds = comprehensiveQueryDto.getUnitIds().split(",");
            for (String unitId : unitIds) {
                Enterprise enterprise = iEnterpriseService.getById(unitId);
                list.add(enterprise);
            }
        }

        //时间段月份
        List<String> monthList = new ArrayList<>();
        if ("1".equals(comprehensiveQueryDto.getTimeGranularity())) {
            monthList = DateBetweenUtil.getYearBetween(comprehensiveQueryDto.getBeginTime(), comprehensiveQueryDto.getEndTime());
        } else if ("2".equals(comprehensiveQueryDto.getTimeGranularity())) {
            monthList = DateBetweenUtil.getSeasonList(comprehensiveQueryDto.getBeginTime(), comprehensiveQueryDto.getEndTime());
        } else {
            monthList = DateBetweenUtil.getMonthBetween(comprehensiveQueryDto.getBeginTime(), comprehensiveQueryDto.getEndTime());
        }
        String start = comprehensiveQueryDto.getBeginTime() + " 00:00:00";
        String end = comprehensiveQueryDto.getEndTime() + " 23:59:59";
        //获取数据
        for (int i = 0; i < monthList.size(); i++) {
            if (i != 0) {
                start = monthList.get(i).substring(0, 7) + "-01 00:00:00";
            }

            if ("1".equals(comprehensiveQueryDto.getTimeGranularity())) {
                String year = monthList.get(i).substring(0, 4);
                String endYear = comprehensiveQueryDto.getEndTime().substring(0, 4);
                if (Integer.parseInt(year) < Integer.parseInt(endYear)) {
                    end = year + "-12-31 23:59:59";
                }
                monthList.set(i, year);
            } else if ("2".equals(comprehensiveQueryDto.getTimeGranularity())) {
                //月份对应季度
                String year = monthList.get(i).substring(0, 4);
                String month = monthList.get(i).substring(5, 7);
                int quarter = (Integer.parseInt(month) + 2) / 3;
                if (quarter == 1) {
                    end = year + "-03-31 23:59:59";
                } else if (quarter == 2) {
                    end = year + "-06-30 23:59:59";
                } else if (quarter == 3) {
                    end = year + "-09-30 23:59:59";
                } else if (quarter == 4) {
                    end = year + "-12-31 23:59:59";
                }
                monthList.set(i, year + "-" + quarter);
            } else {
                end = monthList.get(i) + " 23:59:59";
                monthList.set(i, monthList.get(i).substring(0, 7));
            }

            List<SocialSocreVo> monthSocreVoList = getSocialSocreVoList(list, start, end);

            //list排序
            //根据某个属性分组，汇总某个属性
            Map<String, LongSummaryStatistics> monthResult = new HashMap<>();
            if ("1".equals(comprehensiveQueryDto.getDataDimension())) {
                monthResult = monthSocreVoList.stream().collect(Collectors.groupingBy(SocialSocreVo::getName, Collectors.summarizingLong(SocialSocreVo::getTotalScore)));
            } else if ("2".equals(comprehensiveQueryDto.getDataDimension())) {
                monthResult = monthSocreVoList.stream().collect(Collectors.groupingBy(SocialSocreVo::getAreaName, Collectors.summarizingLong(SocialSocreVo::getTotalScore)));
            } else {
                monthResult = monthSocreVoList.stream().collect(Collectors.groupingBy(SocialSocreVo::getIndustryName, Collectors.summarizingLong(SocialSocreVo::getTotalScore)));
            }
            for (Map.Entry<String, LongSummaryStatistics> entry : monthResult.entrySet()) {
                if (resultMap.containsKey(entry.getKey())) {
                    List<Double> resultList = resultMap.get(entry.getKey());
                    double one = entry.getValue().getAverage();
                    BigDecimal two = new BigDecimal(one);
                    double three = two.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    resultList.add(three);
                    resultMap.put(entry.getKey(), resultList);
                } else {
                    List<Double> resultList = new ArrayList<>();
                    double one = entry.getValue().getAverage();
                    BigDecimal two = new BigDecimal(one);
                    double three = two.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    resultList.add(three);
                    resultMap.put(entry.getKey(), resultList);
                }
            }

        }
        resultData.put("month", monthList);
        resultData.put("data", resultMap);
        return CommonResult.success(resultData);
    }


    private List<SocialSocreVo> getSocialSocreVoList(List<Enterprise> list, String start, String end) {
        List<SocialSocreVo> socreVoList = new ArrayList<>();

        for (Enterprise enterprise : list) {

            DevHisResult devHisResult = devHisResultService.getUnitNum(enterprise.getId().toString(), start, end);

            SocialSocreVo socialSocreVo = new SocialSocreVo();
            socialSocreVo.setId(enterprise.getId());
            socialSocreVo.setName(enterprise.getEnterpriseName());
            socialSocreVo.setAreaName(enterprise.getAreaName());
            socialSocreVo.setIndustryName(enterprise.getIndustryName());

            //火警率得分
            int fireRateScore = devHisService.getFireRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireRateScore(fireRateScore);

            //火警有效复核率
            int fireYXFHScore = 0;
            HashMap<String, Object> params = new HashMap<>(16);
            params.put("beginDate", start);
            params.put("endDate", end);
            params.put("unitId", enterprise.getId().toString());
            //已复核总数
            int total = devHisResult.getReviewAll();
            //有效复核数
            int effect = devHisResult.getReview();
            if (total == 0) {
                fireYXFHScore = 20;
            } else {
                double fhRate = (double) effect / total;
                if (fhRate == 1) {
                    fireYXFHScore = 20;
                }
                if (fhRate > 0.8 && fhRate < 1) {
                    fireYXFHScore = 15;
                }
                if (fhRate <= 0.8) {
                    fireYXFHScore = 0;
                }
            }
            socialSocreVo.setFireYXFHScore(fireYXFHScore);
            //预警有效复核率20分
            int warnFHRate = 0;
            int watertotal = devHisResult.getManagementAll();
            if (0 == watertotal) {
                warnFHRate = 20;
            } else {
                //有效复核数
                int effectWater = devHisResult.getManagement();
                double num = (double) effectWater / (double) watertotal;
                if (num == 1) {
                    warnFHRate = 20;
                }
                if (num > 0.8 && num < 1) {
                    warnFHRate = 15;
                }
                if (num <= 0.8) {
                    warnFHRate = 0;
                }
            }
            socialSocreVo.setWarnFHRate(warnFHRate);
            //故障率（10分）
            int fireGZRateScore = devHisService.getFireGZRateScore(start, end, enterprise.getId().toString());
            socialSocreVo.setFireGZRateScore(fireGZRateScore);
            //消防安全巡查（10分）扣分制
            int safeSocre = iPatrolReportService.getSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setSafeSocre(safeSocre);

            //值班记录10分） 扣分制*
            int zbScore = iDutyRecordService.getSocScore(start, end, enterprise.getId().toString());
            socialSocreVo.setZbScore(zbScore);

            //隐患有效整改率
            int urgmentSocre = urgentMaintenanceService.getSociologyUrgentSocre(start, end, enterprise.getId().toString());
            socialSocreVo.setUrgmentSocre(urgmentSocre);
            int totalSocal = fireRateScore + fireYXFHScore + warnFHRate + fireGZRateScore + safeSocre + zbScore + urgmentSocre;
            socialSocreVo.setTotalScore(totalSocal);
            socreVoList.add(socialSocreVo);

        }
        return socreVoList;
    }

}
